package com.breeze.skinlib

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import java.util.*

class SkinLayoutInflaterFactory : LayoutInflater.Factory2, Observer {
    private var skinAttribute = SkinAttribute()

    // 原生View可能的包名
    private val sClassPrefixList = arrayOf(
        "android.widget.",
        "android.webkit.",
        "android.app.",
        "android.view."
    )

    /**
     * LayoutInflater会调用该方法来创建View，需要区分SDKView和普通View的创建，SDKView需要添加包名，才可以反射创建
     *在该方法中可以收集支持的View以及支持的属性集合
     */
    override fun onCreateView(
        parent: View?,
        name: String,
        context: Context,
        attrs: AttributeSet
    ): View? {
        var view: View? = if (-1 != name.indexOf('.')) {
            createView(name, context, attrs)
        } else {
            createSDKView(name, context, attrs)
        }
        if (view != null) {
            skinAttribute.look(view, attrs)
        }
        return view
    }

    private fun createView(name: String, context: Context, attrs: AttributeSet): View? {
        try {
            var loadClass = context.classLoader.loadClass(name)
            var constructor =
                loadClass.getConstructor(
                    Context::class.java,
                    AttributeSet::class.java
                ) // 调用两个参数构造方法
            return constructor.newInstance(context, attrs) as View
        } catch (e: Exception) {
        }
        return null
    }


    private fun createSDKView(name: String, context: Context, attrs: AttributeSet): View? {
        // 尝试包名，哪个可以创建成功，则哪个包名正确
        for (prefix in sClassPrefixList) {
            val view = createView(prefix + name, context, attrs)
            if (view != null) {
                return view
            }
        }
        return null
    }

    override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
        TODO("Not yet implemented")
    }

    override fun update(o: Observable?, arg: Any?) {
        skinAttribute.applySkin()
    }

}